package zhixu.imclientgui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JButton;

public class Client {

	private String SIP;
	private int SPort;
	private Socket CSocket;
	private BufferedReader sysin;
	
	public Client() {
		super();
	}

	public void init() {
		try {
			sysin = new BufferedReader(new InputStreamReader(System.in));
			System.out.println("Welcom to EIM! ");		
			System.out.println("Server IP:");
			SIP = sysin.readLine();
			System.out.println("Server port:");
			SPort = Integer.parseInt((sysin.readLine()));
			CSocket = new Socket(SIP, SPort);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws Exception {
		Client c = new Client();
		c.init();
		ClientGUI gui = new ClientGUI(c.CSocket);
		new Thread(new ReaderGUI(c.CSocket, gui)).start();
		//new Thread(new WriterGUI(c.CSocket, gui)).start();
		new Thread(new ListRefresh(c.CSocket, gui)).start();
	}
}

class ListRefresh implements Runnable {

	private Socket socket;
	private ClientGUI gui;
	private OutputStream out;
	private BufferedReader in;
		
	public ListRefresh(Socket socket, ClientGUI gui) {
		super();
		this.socket = socket;
		this.gui = gui;
		try {
			out = socket.getOutputStream();
			in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {

		String line;
		String[] words;
		try {
			while (true) {
				Thread.sleep(500);		
				out.write("lsall".getBytes());
				line = in.readLine();
				words = line.split("\\s");
				for(String name:words) {
					JButton btn = new JButton(name);
					gui.sidePan.add(btn);
					btn.addActionListener(new ActionListener() {

						@Override
						public void actionPerformed(ActionEvent e) {
							try {
								out.write(("write " + name + "\n").getBytes());
							} catch (IOException e1) {
								e1.printStackTrace();
							}
						}
					});
				}
				gui.sidePan.setVisible(true);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

class ReaderGUI implements Runnable {

	private BufferedReader in;
	private Socket socket;
	private ClientGUI gui;
	
	public ReaderGUI(Socket socket, ClientGUI gui) {
		super();
		this.socket = socket;
		this.gui = gui;
		try {
			in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		char c;
		while (socket != null && !socket.isClosed() && socket.isConnected() && socket.isBound()) {
			try {
				c = (char)in.read();
				if (c == 4) {
					break;
				}
				gui.ta.append(String.valueOf(c));
				System.out.print(c);
			} catch (IOException e) {
				break;
			}
		}
		try {
			socket.close();
		} catch (IOException e) {
			e.printStackTrace(); //TODO: output to log
		}
	}	
}

class WriterGUI implements Runnable {

	private Socket socket;
	private OutputStream out;
	private BufferedReader sysin;
	private ClientGUI gui;
	
	public WriterGUI(Socket socket, ClientGUI gui) {
		super();
		this.socket = socket;
		this.gui = gui;
		try {
			out = this.socket.getOutputStream();
			sysin = new BufferedReader(new InputStreamReader(System.in));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		String line;
		String encoding=System.getProperty("sun.jnu.encoding");
		try {
			out.write((encoding + "\n").getBytes());
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		while (socket != null && !socket.isClosed()) {
			try {
				//line = sysin.readLine();
				line = gui.tf.getText();
				out.write((line + "\n").getBytes());
			} catch (IOException e) {
				e.printStackTrace();
				break;
			}
		}
		try {
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}